/**
 * Copyright 1996 self.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 *
 * @author Ashin Wimalajeewa
 *
 * Note, this is a very old runtime library that I have evolved since 1996. I rarely use it
 * now because the Apache Commons project has made it obsolete.
 */
package self.math;

public class EllipseEquation {
  public double a, b, h, k;
  
  public EllipseEquation() {
	// nothing to do.
  }
  
  public EllipseEquation( double a, double b, double h, double k ) {
    setCoefficients( a, b, h, k );
  }
  
  public void setCoefficients( double a, double b, double h, double k ) {
    this.a = a;
    this.b = b;
    this.h = h;
    this.k = k;
  }  
  
  public void setBasedOnRectangle( double x, double y, double width, double height ) {
    a = width/2;
    b = height/2;
    h = x + a;
    k = y + b;
  }
  
  /*
  (x-h)^2     (y-k)^2
  ------   +  -------  = 1   & y = mx + c
    a^2         b^2
  
  */
  public boolean getIntersectingPoints( LinearEquation line, double[] xyPoints ) {
    double sqrA = a*a;
    double sqrB = b*b;
    double sqrH = h*h;
    double sqrK = k*k;
    
    double quadA;
    double quadB;
    double quadC;

    if ( line.isXOnlyEquation() ) {
      quadA = sqrA;
      quadB = -2*sqrA*k;
      quadC = sqrA*sqrK - sqrA*sqrB + sqrB*((line.c-h)*(line.c-h));
    } else {
      double sqrM = line.m*line.m;
      double r = line.c-k;
      double sqrR = r*r;
      quadA = sqrB + (sqrA*sqrM);
      quadB = (2*sqrA*line.m*r) - (2*sqrB*h);
      quadC = (sqrB*sqrH) + (sqrA*sqrR) - (sqrA*sqrB);
    }
    
    QuadraticEquation q = new QuadraticEquation( quadA, quadB, quadC );
    double[] xValues = new double[2];
    q.calcXValues( xValues );
    
    if ( line.isXOnlyEquation() ) {
      xyPoints[0] = line.c;
      xyPoints[1] = xValues[0]; // remember X's are actually Y's
      xyPoints[2] = line.c;
      xyPoints[3] = xValues[1];
    } else {
      xyPoints[0] = xValues[0];
      xyPoints[1] = line.solveForX( xyPoints[0] );
      xyPoints[2] = xValues[1];
      xyPoints[3] = line.solveForX( xyPoints[2] );
    }
    boolean noIntersection = ( Double.isNaN(xyPoints[0]) && Double.isNaN(xyPoints[1]) );
    return !noIntersection;
  }
  
  /*
                       b^2(x-h)^2   
   (y-k)^2  -  b^2 +   ------         = 0
                        a^2         

  
   y2 -2ky + k^2 - (const) = 0
  */
  public void solveForX( double xVal, double[] yVals ) {
    double sqrA = a*a;
    double sqrB = b*b;
    double sqrK = k*k;
    double xMinusHAllSqrd = (xVal-h)*(xVal-h);
    double theConst = ((sqrB*xMinusHAllSqrd)/sqrA) - sqrB;
    
    double quadA = 1;
    double quadB = -2*k;
    double quadC = sqrK + theConst;
    
    QuadraticEquation q = new QuadraticEquation( quadA, quadB, quadC );
    q.calcXValues( yVals );
  }
  
  public String toString() {
    return "[a=" + a + ", b=" + b + ", h=" + h + ", k=" + k +"]";
  }
}
